<!--
 * @Descripttion: 课堂分析详情
 * @version: V1.0.0.1
 * @Author: zhaozhenzhuo
 * @Date: 2025-10-22 10:43:57
 * @LastEditors: zhaozhenzhuo
 * @LastEditTime: 2025-10-22 10:43:57
-->
<template>
	<div class="lesson-analysis-details-page">
		<div class="left-wrapper">
			<div class="video-wrapper">
				<MultiPlayer
					ref="multiPlayerRef"
					:vod-list="vodList"
					:enable-url-proxy="enableUrlProxy"
					:video-num="videoNum"
					:video-preview-error-tis="videoPreviewErrorTis"
					@currentTimeChange="onCurrentTimeChange"
					@seeking="onSeeking"
				/>
			</div>
			<div class="text-board-wrapper">
				<CourseTextWide
					id="drawer-wrap-word"
					ref="courseTextRef"
					:current-time="currentTime"
					:lesson-code="lessonCode"
					@changeVideoTime="onChangeVideoTime"
				>
				</CourseTextWide>
			</div>
		</div>
		<div class="right-wrapper">
			<div class="menu-wrapper">
				<div
					v-for="item in menuList"
					:key="item.id"
					class="menu-item"
					:class="{ active: currentMenu === item.id }"
					@click="handleMenuClick(item.id)"
				>
					<p>{{ item.name }}</p>
				</div>
			</div>
			<div class="content-wrapper">
				<!-- ppt抽取 -->
				<PPTIndentify
					v-if="currentMenu === 1"
					:lesson-code="lessonCode"
					@changeVideoTime="onChangeVideoTime"
				/>
				<!-- 知识图谱 -->
				<KnowledgeGraphCom
					v-if="currentMenu === 2"
					:business-code="lessonCode"
					:root-name="lessonInfo?.name || ''"
					type="lesson"
					@changeVideoTime="onChangeVideoTime"
				/>
				<!-- 内容量标 -->
				<ContentStandard
					v-if="currentMenu === 3"
					:lesson-code="lessonCode"
					@changeVideoTime="onChangeVideoTime"
				/>
				<!-- 教学环节 -->
				<TeachingSegment
					v-if="currentMenu === 4"
					:lesson-code="lessonCode"
					@changeVideoTime="onChangeVideoTime"
				/>
				<!-- 教师行为 -->
				<div v-if="currentMenu === 5" class="teaching-behavior-wrapper">
					<div class="teaching-behavior-content-wrapper">
						<!-- 授课时间 -->
						<TeachingTime
							:type="1"
							:query-obj="queryObj"
							:time-table-list="timeTableList"
							:event-time-line-list="eventTimeLineList"
							@changeVideoTime="onChangeVideoTime"
						/>
						<!-- 活动区域 -->
						<TeacherTrajectory
							:query-obj="queryObj"
							:behavior-data="behaviorData"
							:real-break-time-arr="realBreakTimeArr"
							@previewShow="previewShow"
							@changeVideoTime="onChangeVideoTime"
						/>
						<!-- 授课动作 -->
						<TeacherBehavior
							:query-obj="queryObj"
							:config-info="configInfo"
							:real-break-time-arr="realBreakTimeArr"
							@behaviorData="onBehaviorData"
							@previewShow="previewShow"
							@changeVideoTime="onChangeVideoTime"
						/>
						<!-- 授课音量 -->
						<TeachingVolume
							:query-obj="queryObj"
							:real-break-time-arr="realBreakTimeArr"
							@changeVideoTime="onChangeVideoTime"
						/>
						<!-- 授课语速 -->
						<TeachingSpeed
							:query-obj="queryObj"
							:real-break-time-arr="realBreakTimeArr"
							@changeVideoTime="onChangeVideoTime"
						/>
						<!-- 习惯用语 -->
						<KeywordResult
							:query-obj="queryObj"
							:type="1"
							@changeVideoTime="onChangeVideoTime"
							@searchTextBoard="onSearchTextBoard"
						/>
						<!-- 敏感词 -->
						<KeywordResult
							:query-obj="queryObj"
							:type="2"
							@changeVideoTime="onChangeVideoTime"
							@searchTextBoard="onSearchTextBoard"
						/>
						<!-- 课堂提问、鼓励学生提问、操作演示片段 -->
						<QuestionResult :lesson-code="lessonCode" @changeVideoTime="onChangeVideoTime" />
					</div>
				</div>
				<!-- 学生行为 -->
				<div v-if="currentMenu === 6" class="student-behavior-wrapper">
					<div class="student-behavior-content-wrapper">
						<!-- 就座人数 -->
						<SeatingNum
							:lesson-info="props.lessonInfo"
							:aice-config-info="aiceConfigInfo"
							@previewShow="previewShow"
						/>
						<!-- 行为动作 -->
						<BehaviorAction
							:lesson-info="props.lessonInfo"
							:lesson-behavior-detail="sourceLessonBehaviorDetail"
							:step-time="stepTime"
							:video-begin-time="videoBeginTime"
							:config-info="configInfo"
							:real-break-time-arr="realBreakTimeArr"
							@previewShow="previewShow"
						/>
						<!-- 学生发言 -->
						<StudentSpeak
							:query-obj="queryObj"
							:lesson-behavior-detail="lessonBehaviorDetail"
							:step-time="stepTime"
							:real-break-time-arr="realBreakTimeArr"
							@previewShow="previewShow"
							@changeVideoTime="onChangeVideoTime"
						>
							<TeachingTime
								:type="2"
								:query-obj="queryObj"
								:time-table-list="timeTableList"
								:event-time-line-list="eventTimeLineList"
								@changeVideoTime="onChangeVideoTime"
							/>
						</StudentSpeak>
					</div>
				</div>
				<!-- 其他内容 -->
				<div v-if="currentMenu === 7" class="other-content-wrapper">
					<!-- 课堂内容概要 -->
					<TeachingContent :lesson-code="lessonCode" />
					<!-- 教学优缺点 -->
					<TeachingProsAndCons :lesson-code="lessonCode" />
					<!-- 语言表达 -->
					<LanguageExpression :lesson-code="lessonCode" />
					<!-- 知识要点 -->
					<KnowledgePoint
						:lesson-code="lessonCode"
						@changeVideoTime="onChangeVideoTime"
						@searchTextBoard="onSearchTextBoard"
					/>
				</div>
				<!-- 量化分析 -->
				<div v-if="currentMenu === 8" class="quantitative-analysis-wrapper">
					<!-- 节点详情弹框 -->
					<NodeInfoDialog
						:is-visible-node-info-dialog="true"
						:lesson-info="lessonInfo"
						type="lesson"
						:module-show="{
							nodeTitleShow: false,
							lessonInfoBlockShow: true,
							moduleTitleShow: true,
							knowledgePointBlockShow: true,
							teachingAccuracyBlockShow: true,
							teacherLectureBlockShow: true,
							lessonSectionBlockShow: true,
							teacherBehaviorBlockShow: true,
							teacherLanguageBlockShow: true,
							teacherQuestionBlockShow: true,
							teacherStudentInteractionBlockShow: true,
							relationBlockShow: false,
							videoBlockShow: false,
							lessonAnalysisBlockShow: false,
							footerShow: false
						}"
						:data="{
							knowledgeDetail: [],
							knowledgeRelation: []
						}"
					></NodeInfoDialog>
				</div>
				<AsideBar
					v-if="currentMenu === 5"
					:list="teacherAsideList"
					:height-list="teacherHeightList"
					scrollContainerName="teaching-behavior-wrapper"
				/>
				<AsideBar
					v-if="currentMenu === 6"
					:list="studentAsideList"
					:height-list="studentHeightList"
					scrollContainerName="student-behavior-wrapper"
				/>
			</div>
		</div>

		<!-- 图片预览 -->
		<el-dialog
			v-model="fileDialogVisible"
			:title="previewInfo?.name"
			class="self-dialog preview-dialog"
			align-center
			:close-on-click-modal="false"
		>
			<div class="content">
				<div class="preview-wrapper">
					<PreviewFile
						v-if="fileDialogVisible"
						:preview-info="previewInfo"
						@changeVideoTime="onChangeVideoTime"
						@closePreview="fileDialogVisible = false"
					></PreviewFile>
				</div>
			</div>
			<template #footer>
				<div class="dialog-footer">
					<el-button @click="fileDialogVisible = false">关 闭</el-button>
				</div>
			</template>
		</el-dialog>
	</div>
</template>

<script setup lang="ts">
import { v4 as uuidv4 } from 'uuid';
import { ref, onMounted, getCurrentInstance, onUnmounted, nextTick, watch } from 'vue';
import { getErrorMessage } from '@/api/index';
import { useRoute, useRouter } from 'vue-router';
import type {
	CourseListItemType,
	AnalysisResultType,
	BehaviorDataType,
	AICEConfigInfoType,
	LessonBehaviorDetailItemType,
	TimeTableListItemType,
	EventLineItemType,
	RecordTaskType,
	PreviewInfoType,
	AsideListItemType,
	AsideHeightListItemType,
	RealBreakTimeItemType
} from './LessonAnalysisDetails.typs';
import {
	getEditConfigAPI,
	getAIASConfigAPI,
	getAnalysisResultAPI,
	getResourceByLessonCodeAPI,
	getAILessonBehaviorDetailAPI,
	getTimeTableListAPI,
	getEventTimeLineAPI
} from '@/api/index';
import { isJSONString, formatTime } from '@/assets/js/utils';
import MultiPlayer from '@/components/player/MultiPlayer.vue';
import PreviewFile from '@/components/player/PreviewFile.vue';
import AsideBar from '@/components/lessonAnalysisDetails/AsideBar.vue';
import CourseTextWide from '@/components/lessonAnalysisDetails/CourseTextWide.vue';
import PPTIndentify from '@/components/lessonAnalysisDetails/PPTIndentify.vue';
import KnowledgeGraphCom from '@/components/graph/KnowledgeGraphCom.vue';
import ContentStandard from '@/components/lessonAnalysisDetails/ContentStandard.vue';
import TeachingSegment from '@/components/lessonAnalysisDetails/TeachingSegment.vue';
import TeachingTime from '@/components/lessonAnalysisDetails/teacherBehavior/TeachingTime.vue';
import TeacherTrajectory from '@/components/lessonAnalysisDetails/teacherBehavior/TeacherTrajectory.vue';
import TeacherBehavior from '@/components/lessonAnalysisDetails/teacherBehavior/TeacherBehavior.vue';
import TeachingVolume from '@/components/lessonAnalysisDetails/teacherBehavior/TeachingVolume.vue';
import TeachingSpeed from '@/components/lessonAnalysisDetails/teacherBehavior/TeachingSpeed.vue';
import KeywordResult from '@/components/lessonAnalysisDetails/teacherBehavior/KeywordResult.vue';
import QuestionResult from '@/components/lessonAnalysisDetails/teacherBehavior/QuestionResult.vue';
import SeatingNum from '@/components/lessonAnalysisDetails/studentBehavior/SeatingNum.vue';
import BehaviorAction from '@/components/lessonAnalysisDetails/studentBehavior/BehaviorAction.vue';
import StudentSpeak from '@/components/lessonAnalysisDetails/studentBehavior/StudentSpeak.vue';
import TeachingContent from '@/components/lessonAnalysisDetails/otherContent/TeachingContent.vue';
import TeachingProsAndCons from '@/components/lessonAnalysisDetails/otherContent/TeachingProsAndCons.vue';
import LanguageExpression from '@/components/lessonAnalysisDetails/otherContent/LanguageExpression.vue';
import KnowledgePoint from '@/components/lessonAnalysisDetails/otherContent/KnowledgePoint.vue';
import NodeInfoDialog from '@/components/common/NodeInfoDialog.vue';

// 定义 props
const props = withDefaults(
	defineProps<{
		lessonInfo: CourseListItemType | null;
	}>(),
	{
		lessonInfo: null
	}
);

const route = useRoute();
const router = useRouter();
// 在 setup 顶层获取实例
const instance = getCurrentInstance();

// 每次采样间隔时间(min)
const stepTime = ref<number>(5);
// 是否启用URL代理
const enableUrlProxy = ref<boolean>(window.$dataConfig.enableUrlProxy);
// 初始化显示的信源个数
const videoNum = ref<number>(window.$dataConfig.videoNum);
// 播放器错误提示
const videoPreviewErrorTis = ref<string>(window.$dataConfig.videoPreviewErrorTis);

onMounted(() => {
	// 初始化URL tab参数
	initTabFromQuery();
	// 初始化
	init();
});

onUnmounted(() => {
	destroyHeight();
});

// 课堂code
const lessonCode = ref<string>(route.query.lessonCode as string);

// 监听 lessonInfo 变化
watch(
	() => props.lessonInfo,
	(newVal) => {
		if (newVal) {
			nextTick(() => {
				initLessonData();
			});
		}
	},
	{ immediate: true }
);
// 菜单列表
const menuList = [
	{
		name: 'PPT抽取',
		id: 1
	},
	{
		name: '知识图谱',
		id: 2
	},
	{
		name: '内容量标',
		id: 3
	},
	{
		name: '教学环节',
		id: 4
	},
	{
		name: '教师行为',
		id: 5
	},
	{
		name: '学生行为',
		id: 6
	},
	{
		name: '其他内容',
		id: 7
	},
	{
		name: '量化分析',
		id: 8
	}
];
// 当前的菜单
const currentMenu = ref<number>(-1);
// 初始化tab参数
const initTabFromQuery = () => {
	const tab = route.query.tab;
	if (!tab) {
		// 如果没有tab参数，设置默认tab=2
		router.replace({
			query: {
				...route.query,
				tab: '2'
			}
		});
		currentMenu.value = 2;
	} else {
		// 如果有tab参数，设置对应的currentMenu
		const tabNum = parseInt(tab as string);
		if (tabNum >= 1 && tabNum <= 8) {
			currentMenu.value = tabNum;
		} else {
			// 如果tab参数不合法，重置为2
			router.replace({
				query: {
					...route.query,
					tab: '2'
				}
			});
			currentMenu.value = 2;
		}
	}

	if (currentMenu.value === 5 || currentMenu.value === 6) {
		nextTick(() => {
			initHeight();
		});
	}
};
// ai分析结果
const aiScoreResult = ref<AnalysisResultType | null>(null);
// 视频开始录制的时间戳
const videoBeginTime = ref<number>(0);
// 视频开始时间和上课开始时间的偏移量
const offsetTime = ref<number>(0);
// 合并后的参数
const queryObj = ref<{
	lessonInfo: CourseListItemType | null;
	aiScoreResult: AnalysisResultType | null;
	offsetTime: number;
	videoBeginTime: number;
} | null>(null);

// 初始化
const init = async () => {
	getConfig();
	getAIASConfig();
};

// 配置信息
const configInfo = ref<Record<string, unknown> | null>(null);
// 获取配置信息
const getConfig = async () => {
	const aiConfigInfo = window.$aiConfigInfo as Record<string, unknown>;

	try {
		const data = await getEditConfigAPI({ isFront: 1 });

		// 解析成需要的格式，将schoolReport、courseReport和lessonReport中的内容平铺
		let _configInfo: Record<string, unknown> | null = null;
		if (data && data.moduleList) {
			const _moduleList = data.moduleList;
			_configInfo = {
				...(_moduleList.schoolReport as Record<string, unknown>),
				...(_moduleList.courseReport as Record<string, unknown>),
				...(_moduleList.lessonReport as Record<string, unknown>)
			};
		}

		if (_configInfo && Object.prototype.toString.call(_configInfo) === '[object Object]') {
			// 解析为对象保存
			const studentBehavior = _configInfo.studentBehavior as Record<string, unknown>;
			(studentBehavior as Record<string, unknown>).hideAll = true; // 是否隐藏全部行为
			const nodeList = (studentBehavior as Record<string, unknown>).nodeList as Record<
				string,
				unknown
			>;
			Object.keys(nodeList).forEach((key) => {
				const item = nodeList[key] as Record<string, unknown>;
				if (item && (item as Record<string, unknown>).show) {
					(studentBehavior as Record<string, unknown>).hideAll = false;
				}
			});
			configInfo.value = _configInfo;
		} else {
			// 兼容异常
			configInfo.value = aiConfigInfo;
		}
	} catch (err) {
		console.error(getErrorMessage(err));
		configInfo.value = aiConfigInfo;
	}
};

// aice配置信息
const aiceConfigInfo = ref<AICEConfigInfoType | null>(null);
// 获取aice配置信息
const getAIASConfig = async () => {
	const _aiceConfigInfo = window.$aiceConfigInfo as unknown as AICEConfigInfoType;

	try {
		const data = await getAIASConfigAPI();

		if (!data) {
			// 兼容异常
			aiceConfigInfo.value = _aiceConfigInfo;
			return;
		}
		if (data.behaviorSourceConfig) {
			data.behaviorSourceConfig = isJSONString(data.behaviorSourceConfig as string) as Record<
				string,
				unknown
			>;
		} else {
			data.behaviorSourceConfig = _aiceConfigInfo.behaviorSourceConfig as Record<string, unknown>;
		}
		aiceConfigInfo.value = data;
	} catch (err) {
		console.error(getErrorMessage(err));
		aiceConfigInfo.value = _aiceConfigInfo;
	}
};

const behaviorData = ref<BehaviorDataType | null>(null);
const onBehaviorData = (info: BehaviorDataType) => {
	behaviorData.value = info;
};

// 初始化课堂相关数据
const initLessonData = async () => {
	if (!props.lessonInfo) return;

	// 查询课堂行为详细信息
	getAILessonBehaviorDetail();
	// 查询AI分析结果和流信息
	Promise.all([
		getAnalysisResult(),
		getResourceByLessonCode(),
		getTimeTableList(),
		getEventTimeLine()
	]).then(() => {
		// 设置课堂时间
		judgeLessonTime();
		// 计算偏移时间
		if (aiScoreResult.value && aiScoreResult.value.calBeginTime && videoBeginTime.value) {
			offsetTime.value =
				aiScoreResult.value.calBeginTime - videoBeginTime.value < 0
					? 0
					: aiScoreResult.value.calBeginTime - videoBeginTime.value;
		}
		queryObj.value = {
			lessonInfo: props.lessonInfo,
			aiScoreResult: aiScoreResult.value,
			offsetTime: offsetTime.value,
			videoBeginTime: videoBeginTime.value
		};
	});
};

// 作息时间表
const timeTableList = ref<TimeTableListItemType[]>([]);
// 获取作息时间表，用于获取计划课间时间
const getTimeTableList = async () => {
	const searchDay = formatTime(props.lessonInfo?.planBeginTime || 0, 'YYYY-MM-DD HH:mm:ss');
	try {
		const data = await getTimeTableListAPI({ searchDay });

		timeTableList.value = data || [];
	} catch (err) {
		console.error(getErrorMessage(err));
	}
};

// 实际事件数组
const eventTimeLineList = ref<EventLineItemType[]>([]);
// 获取实际课间休息时间
const getEventTimeLine = async () => {
	try {
		const data = await getEventTimeLineAPI(props.lessonInfo?.code as string);
		eventTimeLineList.value = data || [];
	} catch (err) {
		console.error(getErrorMessage(err));
	}
};

// 查询指定课堂AI分析结果
const getAnalysisResult = async () => {
	try {
		const data = await getAnalysisResultAPI(props.lessonInfo?.code as string);
		aiScoreResult.value = data || null;
	} catch (err) {
		console.error(getErrorMessage(err));
	}
};

// 实际休息时间数组
const realBreakTimeArr = ref<RealBreakTimeItemType[]>([]);
// 重新计算各种时间
const judgeLessonTime = () => {
	// 计算计划课间休息时间
	let _planBreakTime = 0;
	const _planBreakArr: number[][] = [];
	if (props.lessonInfo?.beginOrder !== props.lessonInfo?.endOrder) {
		timeTableList.value.forEach((item, index) => {
			if (
				props.lessonInfo?.beginOrder &&
				props.lessonInfo?.endOrder &&
				item.classOrder >= props.lessonInfo?.beginOrder &&
				timeTableList.value[index + 1] &&
				timeTableList.value[index + 1].classOrder <= props.lessonInfo?.endOrder
			) {
				const _beginTime = new Date(
					`${formatTime(new Date(props.lessonInfo?.planBeginTime), 'YYYY-MM-DD')} ${item.endTime}`
				).getTime();
				const _endTime = new Date(
					`${formatTime(new Date(props.lessonInfo?.planBeginTime), 'YYYY-MM-DD')} ${
						timeTableList.value[index + 1].beginTime
					}`
				).getTime();
				_planBreakArr.push([_beginTime, _endTime]);
				_planBreakTime += _endTime - _beginTime;
			}
		});
	}

	if (aiScoreResult.value) {
		aiScoreResult.value.planBreakTime = Math.floor(_planBreakTime / 60000) * 60000;
		// 计算实际课间休息时间
		let _realBreakTime = 0;
		const _realBreakArr: RealBreakTimeItemType[] = [];
		eventTimeLineList.value.forEach((item, index) => {
			if (
				item.eventType === 1004 &&
				eventTimeLineList.value[index + 1] &&
				eventTimeLineList.value[index + 1].eventType === 1005
			) {
				_realBreakArr.push({
					startTime: item.eventTime + videoBeginTime.value,
					endTime: eventTimeLineList.value[index + 1].eventTime + videoBeginTime.value
				});
				_realBreakTime += eventTimeLineList.value[index + 1].eventTime - item.eventTime;
			}
		});
		realBreakTimeArr.value = _realBreakArr;
		aiScoreResult.value.realBreakTime = Math.floor(_realBreakTime / 60000) * 60000;
		// 计算老师讲课时长的偏差，开始时间和结束时间的取整偏差算作老师讲课
		let _teachTimeOffset = 0;
		// 将延迟上课时间、提前下课时间、延迟下课时间向下取整，判断是否是异常情况通过后台返回的abnormalType字段
		// abnormal字段为7位字符串，每一位代表一个异常情况，与DataBoard组件中逻辑一致
		if (
			aiScoreResult.value &&
			aiScoreResult.value.abnormalType &&
			aiScoreResult.value.abnormalType[0] === '1'
		) {
			const _lateBeginTime = Math.floor(aiScoreResult.value.lateBeginTime / 60000) * 60000;
			aiScoreResult.value.calLateBeginTime = _lateBeginTime;
			aiScoreResult.value.calBeginTime = (props.lessonInfo?.planBeginTime || 0) + _lateBeginTime;
			_teachTimeOffset += aiScoreResult.value.beginTime - aiScoreResult.value.calBeginTime;
		} else if (aiScoreResult.value) {
			aiScoreResult.value.calLateBeginTime = 0;
			aiScoreResult.value.calBeginTime = Math.floor(aiScoreResult.value.beginTime / 60000) * 60000;
		}
		if (
			aiScoreResult.value &&
			aiScoreResult.value.abnormalType &&
			aiScoreResult.value.abnormalType[1] === '1'
		) {
			// 早退
			const _earlyStopTime = Math.floor(aiScoreResult.value.earlyStopTime / 60000) * 60000;
			aiScoreResult.value.calEarlyStopTime = _earlyStopTime;
			aiScoreResult.value.calEndTime =
				(props.lessonInfo?.planEndTime || 0) -
				(aiScoreResult.value.calEarlyStopTime +
					(aiScoreResult.value.planBreakTime - aiScoreResult.value.realBreakTime > 0
						? aiScoreResult.value.planBreakTime - aiScoreResult.value.realBreakTime
						: 0));
			_teachTimeOffset += aiScoreResult.value.calEndTime - aiScoreResult.value.endTime;
		} else if (
			aiScoreResult.value &&
			aiScoreResult.value.abnormalType &&
			aiScoreResult.value.abnormalType[2] === '1'
		) {
			// 拖堂
			const _lateStopTime = Math.floor(aiScoreResult.value.lateStopTime / 60000) * 60000;
			aiScoreResult.value.calLateStopTime = _lateStopTime;
			aiScoreResult.value.calEndTime = (props.lessonInfo?.planEndTime || 0) + _lateStopTime;
			_teachTimeOffset += aiScoreResult.value.calEndTime - aiScoreResult.value.endTime;
		} else if (aiScoreResult.value) {
			aiScoreResult.value.calEarlyStopTime = 0;
			aiScoreResult.value.calLateStopTime = 0;
			aiScoreResult.value.calEndTime = Math.floor(aiScoreResult.value.endTime / 60000) * 60000;
		}
		// 重新计算课堂总时长
		if (aiScoreResult.value && aiScoreResult.value.calBeginTime && aiScoreResult.value.calEndTime) {
			// 实际结束时间 - 实际开始时间 - 课间实际休息时间
			aiScoreResult.value.calTotalTime =
				aiScoreResult.value.calEndTime -
				aiScoreResult.value.calBeginTime -
				aiScoreResult.value.realBreakTime;
		}
		// 计划上课时长
		if (aiScoreResult.value && props.lessonInfo?.planBeginTime && props.lessonInfo?.planEndTime) {
			// 计划结束时间 - 计划开始时间 - 课间时间
			aiScoreResult.value.planTotalTime =
				props.lessonInfo?.planEndTime -
				props.lessonInfo?.planBeginTime -
				aiScoreResult.value.planBreakTime;
		}
		// 重新计算老师讲课时长
		aiScoreResult.value.calTeachTime = aiScoreResult.value.teachTime + _teachTimeOffset;
	}
};

// 点播列表
const vodList = ref<RecordTaskType[]>([]);
// 获取流地址
const getResourceByLessonCode = async () => {
	try {
		const proxy = instance?.proxy;
		const is404 = proxy?.$globalData?.is404;
		const data = await getResourceByLessonCodeAPI(
			props.lessonInfo?.code as string,
			typeof is404 === 'boolean' ? is404 : true
		);

		if (data?.length) {
			videoBeginTime.value = data.find((item) => item.startTime)?.startTime || 0;
			// 兼容原接口
			if (typeof videoBeginTime.value === 'string') {
				videoBeginTime.value = new Date(videoBeginTime.value)?.getTime() || 0;
			}
		}
		// 如果录制的时间和planBeginTime相差7小时以上，就调整videoBeginTime
		if (
			props.lessonInfo?.planBeginTime &&
			Math.abs(videoBeginTime.value - props.lessonInfo?.planBeginTime) >= 7 * 60 * 60 * 1000
		) {
			if (videoBeginTime.value > props.lessonInfo?.planBeginTime) {
				videoBeginTime.value -= 8 * 60 * 60 * 1000;
			} else {
				videoBeginTime.value += 8 * 60 * 60 * 1000;
			}
		}

		if (data?.length) {
			vodList.value = data.map((item) => {
				item.isCovered = item.status === 6;
				item.isDelete = item.status === 7;
				item.purpose = item.device.purpose;
				item.sourceCode = item.device.id ? String(item.device.id) : uuidv4();
				item.sourceName = item.device.name;
				return item;
			});

			// 录像文件添加索引
			vodList.value.forEach((item) => {
				item.files.forEach((file, index) => {
					file.index = index;
				});
			});
		}
	} catch (err) {
		console.error(getErrorMessage(err));
	}
};

// 课堂行为详细数据(过滤)
const lessonBehaviorDetail = ref<LessonBehaviorDetailItemType[]>([]);
// 课堂行为详细数据(原始)
const sourceLessonBehaviorDetail = ref<LessonBehaviorDetailItemType[]>([]);
// 查询课堂行为详细数据
const getAILessonBehaviorDetail = async () => {
	try {
		const data = await getAILessonBehaviorDetailAPI(props.lessonInfo?.code as string);

		if (data.filterResultList && data.filterResultList.length) {
			// 排序
			data.filterResultList.sort((a, b) => {
				return a.orders - b.orders;
			});
			// 给缺少的数据补0
			data.filterResultList.forEach((item, index) => {
				// 前面补零
				if (index === 0 && item.orders === 1) {
					data.filterResultList.unshift({
						activityAvg: item.activityAvg,
						focusAvg: item.focusAvg,
						orders: 0,
						behaviorData: []
					});
				}
			});
			lessonBehaviorDetail.value = data.filterResultList || [];
		} else {
			lessonBehaviorDetail.value = [];
		}
		if (data.sourceResultList && data.sourceResultList.length) {
			data.sourceResultList.sort((a, b) => {
				return a.orders - b.orders;
			});
			data.sourceResultList.forEach((item, index) => {
				// 前面补零
				if (index === 0 && item.orders === 1) {
					data.sourceResultList.unshift({
						activityAvg: item.activityAvg,
						focusAvg: item.focusAvg,
						orders: 0,
						behaviorData: []
					});
				}
			});
			sourceLessonBehaviorDetail.value = data.sourceResultList || [];
		} else {
			sourceLessonBehaviorDetail.value = [];
		}
	} catch (err) {
		console.error(getErrorMessage(err));
	}
};

// 播放器ref
const multiPlayerRef = ref<InstanceType<typeof MultiPlayer> | null>(null);
// 跳转视频时间
const onChangeVideoTime = (time: number) => {
	console.log('修改时间', time);
	multiPlayerRef.value?.changeVideoTime(time);
};

// 当前播放时间
const currentTime = ref<number>(0);
// 当前时间改变
const onCurrentTimeChange = (time: number) => {
	currentTime.value = time;
};
// 文字看板ref
const courseTextRef = ref<InstanceType<typeof CourseTextWide> | null>(null);
// seeking事件
const onSeeking = () => {
	courseTextRef.value?.setAutoPlayFlag(true);
};
// 搜索文字看板
const onSearchTextBoard = (name: string) => {
	courseTextRef.value?.onSearchTextBoardHandle(name, true);
};

// 预览相关信息
const previewInfo = ref<PreviewInfoType | null>(null);
// 预览弹框显示隐藏状态
const fileDialogVisible = ref<boolean>(false);
// 预览图片
const previewShow = (info: PreviewInfoType) => {
	previewInfo.value = info;
	fileDialogVisible.value = true;
};

// 菜单点击
const handleMenuClick = (id: number) => {
	if (currentMenu.value === id) {
		return;
	}
	if (currentMenu.value === 5 || currentMenu.value === 6) {
		destroyHeight();
	}
	currentMenu.value = id;

	// 同步更新URL的tab参数
	router.replace({
		query: {
			...route.query,
			tab: String(id)
		}
	});

	if (id === 5 || id === 6) {
		nextTick(() => {
			initHeight();
		});
	}
};

/** 侧边栏相关 */
// 侧边栏列表
const teacherAsideList = ref<AsideListItemType[]>([
	{ id: 1, name: '授课时间' },
	{ id: 2, name: '活动区域' },
	{ id: 3, name: '授课动作' },
	{ id: 4, name: '授课音量' },
	{ id: 5, name: '授课语速' },
	{ id: 6, name: '习惯用语' },
	{ id: 7, name: '敏感词' },
	{ id: 8, name: '课堂提问' },
	{ id: 9, name: '鼓励学生提问' },
	{ id: 10, name: '操作演示' }
]);
const studentAsideList = ref<AsideListItemType[]>([
	{ id: 1, name: '就座人数' },
	{ id: 2, name: '行为动作' },
	{ id: 3, name: '学生发言' }
]);
// 侧边栏高度数据
const teacherHeightList = ref<AsideHeightListItemType[]>([]);
const studentHeightList = ref<AsideHeightListItemType[]>([]);
// 元素高度变化的回调
const handleTeacherResize = () => {
	teacherHeightList.value = [
		{
			id: 1,
			height: (document.querySelector('.teaching-time-wrapper') as HTMLElement)?.offsetTop || 0
		},
		{
			id: 2,
			height: (document.querySelector('.teacher-trajectory-wrapper') as HTMLElement)?.offsetTop || 0
		},
		{
			id: 3,
			height: (document.querySelector('.teacher-behavior-wrapper') as HTMLElement)?.offsetTop || 0
		},
		{
			id: 4,
			height: (document.querySelector('.teaching-volume-wrapper') as HTMLElement)?.offsetTop || 0
		},
		{
			id: 5,
			height: (document.querySelector('.teaching-speed-wrapper') as HTMLElement)?.offsetTop || 0
		},
		{
			id: 6,
			height: (document.querySelector('.common-slang-wrapper') as HTMLElement)?.offsetTop || 0
		},
		{
			id: 7,
			height: (document.querySelector('.sensitive-word-wrapper') as HTMLElement)?.offsetTop || 0
		},
		{
			id: 8,
			height:
				(document.querySelector('.question-result-wrapper .module-wrapper-0') as HTMLElement)
					?.offsetTop || 0
		},
		{
			id: 9,
			height:
				(document.querySelector('.question-result-wrapper .module-wrapper-1') as HTMLElement)
					?.offsetTop || 0
		},
		{
			id: 10,
			height:
				(document.querySelector('.question-result-wrapper .module-wrapper-2') as HTMLElement)
					?.offsetTop || 0
		}
	];
};
const handleStudentResize = () => {
	studentHeightList.value = [
		{
			id: 1,
			height: (document.querySelector('.seating-num-wrapper') as HTMLElement)?.offsetTop || 0
		},
		{
			id: 2,
			height: (document.querySelector('.behavior-action-wrapper') as HTMLElement)?.offsetTop || 0
		},
		{
			id: 3,
			height: (document.querySelector('.student-speak-wrapper') as HTMLElement)?.offsetTop || 0
		}
	];
};

const teacherResizeObserver = ref<ResizeObserver | null>(null);
const studentResizeObserver = ref<ResizeObserver | null>(null);
// 初始化绑定高度
const initHeight = () => {
	// 监听teacher-behavior-content-wrapper元素大小变化
	const teacherContentDetailRef: HTMLElement | null = document.querySelector(
		'.teaching-behavior-content-wrapper'
	);
	if (teacherContentDetailRef) {
		teacherResizeObserver.value = new ResizeObserver(() => {
			// 当DOM元素的宽高发生变化时执行回调函数
			handleTeacherResize();
		});
		teacherResizeObserver.value.observe(teacherContentDetailRef);
	}

	// 监听student-behavior-content-wrapper元素大小变化
	const studentContentDetailRef: HTMLElement | null = document.querySelector(
		'.student-behavior-content-wrapper'
	);
	if (studentContentDetailRef) {
		studentResizeObserver.value = new ResizeObserver(() => {
			// 当DOM元素的宽高发生变化时执行回调函数
			handleStudentResize();
		});
		studentResizeObserver.value.observe(studentContentDetailRef);
	}
};
// 解除绑定
const destroyHeight = () => {
	if (teacherResizeObserver.value) {
		teacherResizeObserver.value.disconnect();
		teacherResizeObserver.value = null;
	}
	if (studentResizeObserver.value) {
		studentResizeObserver.value.disconnect();
		studentResizeObserver.value = null;
	}
};
</script>
<style scoped lang="scss">
.lesson-analysis-details-page {
	position: relative;
	height: 100%;
	display: flex;
	align-items: center;
	justify-content: space-between;

	.left-wrapper {
		padding-left: 1.6rem;
		padding-bottom: 1.6rem;
		width: 53%;
		height: 100%;

		.video-wrapper {
			width: 100%;
			height: 50%;
		}

		.text-board-wrapper {
			width: 100%;
			height: 50%;
		}
	}

	.right-wrapper {
		padding-top: 0.8rem;
		width: 47%;
		height: 100%;
		background-color: #ffffff;
		border-radius: 0.8rem 0.8rem 0px 0px;
		border: 1px solid #f5f7ff;

		.menu-wrapper {
			display: flex;
			align-items: center;
			font-size: $font-size-base;
			color: $text-color-primary;
			border-bottom: 1px solid $border-color-primary;

			.menu-item {
				margin-left: 2rem;
				padding: 0 0.7rem;
				height: 3.2rem;
				line-height: 3.2rem;
				cursor: pointer;

				&.active {
					color: $color-brand;
					border-bottom: 2px solid $color-brand;
				}
			}
		}

		.content-wrapper {
			position: relative;
			height: calc(100% - 3.2rem);

			:deep(.fragment-btn-wrapper) {
				display: flex;
				align-items: center;
				gap: 1rem;
				margin-top: 1.6rem;
				padding: 0 1.2rem;
				width: fit-content;
				height: 3.2rem;
				line-height: 3.2rem;
				font-size: $font-size-small-1;
				color: $color-brand;
				border-radius: 0.4rem;
				border: 1px solid $color-brand;
				cursor: pointer;

				svg {
					width: $font-size-small-1;
					height: $font-size-small-1;
				}
			}

			:deep(.fragment-content-wrapper) {
				flex: 1;
				min-height: 0;
				display: flex;
				flex-direction: column;
				gap: 0.8rem;
				position: relative;
				margin-top: 1.6rem;
				overflow-y: auto;

				.content-item {
					padding: 1.2rem;
					background-color: rgba($color: $bg-block-color-primary, $alpha: 0.7);
					border-radius: 0.8rem;
					cursor: pointer;

					&:hover {
						background-color: color.adjust($color-brand, $lightness: 38%);

						.edit-icon {
							display: flex !important;
						}

						.left-info {
							.time {
								color: $text-color-brand !important;
							}
						}
					}

					.top-wrapper {
						display: flex;
						justify-content: space-between;
						align-items: center;
						gap: 1rem;
						white-space: nowrap;

						.left-info {
							display: flex;
							align-items: center;
							gap: 6rem;
							line-height: 1;

							.time {
								color: $text-color-regular;
							}
						}

						.edit-icon {
							display: none;
							align-items: center;
							gap: 1.6rem;

							img {
								width: $font-size-base;
								height: $font-size-base;
								cursor: pointer;
							}

							svg {
								width: $font-size-small-1;
								height: $font-size-small-1;
								color: $color-danger;
								cursor: pointer;
							}
						}

						.right-info {
							display: flex;
							align-items: center;
							gap: 1rem;

							.right-info-btn {
								padding: 0 1.3rem;
								height: 2.4rem;
								background-color: $bg-block-color-brand;
								border-radius: 1.2rem;
								line-height: 2.4rem;
								font-size: $font-size-small-1;
								color: color.adjust($text-color-brand, $lightness: 10%);
							}
						}
					}

					.title-wrapper {
						margin-top: 1.1rem;
						margin-bottom: 0.7rem;
						color: $text-color-primary;
						font-family: $font-family-bold;
					}

					.detail-wrapper {
						color: $text-color-regular;
						font-size: $font-size-small-1;
					}
				}
			}

			:deep(.module-title-wrapper) {
				display: flex;
				align-items: center;
				position: relative;
				padding-left: 1rem;
				font-size: $font-size-large-1;
				color: $text-color-primary;

				&::before {
					content: '';
					position: absolute;
					top: 50%;
					left: 0;
					transform: translateY(-50%);
					width: 0.2rem;
					height: $font-size-base;
					background-color: $color-brand;
					border-radius: 0.1rem;
				}

				img {
					width: $font-size-base;
					height: $font-size-base;
					margin-left: 1.6rem;
					cursor: pointer;
				}
			}

			:deep(.detail) {
				margin-top: 1.5rem;
				margin-bottom: 0.5rem;

				p {
					font-size: $font-size-small-1;
					color: $text-color-regular;

					.active {
						color: $text-color-brand;
						font-family: $font-family-bold;
					}

					.red {
						color: $text-color-danger;
						font-family: $font-family-bold;
					}

					.green {
						color: $text-color-success;
						font-family: $font-family-bold;
					}
				}
			}

			.teaching-behavior-wrapper,
			.student-behavior-wrapper,
			.other-content-wrapper,
			.quantitative-analysis-wrapper {
				padding: 1.6rem;
				padding-right: 3.2rem;
				height: 100%;
				overflow-y: auto;
			}

			.other-content-wrapper {
				padding-right: 1.6rem;
			}

			.quantitative-analysis-wrapper {
				padding-top: 0;
				padding-right: 0;

				:deep(.node-info-dialog) {
					position: static;
					padding: 0;
					width: 100%;
					height: 100%;
					background: none;
					box-shadow: none;
					border-radius: 0;

					.close-icon {
						display: none;
					}

					.content-wrapper {
						padding-right: 1.6rem;
					}
				}
			}
		}
	}
}

.preview-dialog {
	.el-button {
		padding: 0.8rem 1.5rem;
		height: 3.2rem;
		border-radius: 0.4rem;
	}
}
</style>
